import os
import json
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import WatermarkTemplate, FileManagement
from mongolog.models import FileLog
from mongolog.pymongo_client import collections, py_dbclient
from .serializers import WatermarkTemplateSerializer
from tools.utils import file_md5
from zmad.models import ZTPUser
from userdata.models import UserScore

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Create your views here.


class WatermarkTemplateViewSet(mixins.ListModelMixin,
                               mixins.RetrieveModelMixin,
                               mixins.DestroyModelMixin,
                               mixins.UpdateModelMixin,
                               mixins.CreateModelMixin,
                               GenericViewSet):
    """水印模板视图类"""
    queryset = WatermarkTemplate.objects.all()
    serializer_class = WatermarkTemplateSerializer


@api_view(["GET", "POST", "DELETE"])
def file_management(request):
    res = dict()
    res["status"] = 0
    res["msg"] = "success"
    if request.method == "GET":
        file_type = request.GET.get("type")
        if file_type:
            fmobjects = FileManagement.objects.filter(status=1, file_type=file_type).all()
        else:
            fmobjects = FileManagement.objects.filter(status=1).all()
        res["data"] = list()
        for obj in fmobjects:
            temp_dict = dict()
            temp_dict["type"] = obj.file_type
            temp_dict["content"] = obj.name
            temp_dict["level"] = obj.level
            temp_dict["datetime"] = obj.create_time
            temp_dict["id"] = obj.id
            res["data"].append(temp_dict)
    elif request.method == "POST":
        param = request.data
        file_type = int(param.get("type"))
        level = int(param.get("level"))
        sensitive_word = ""
        if file_type == 2:
            sensitive_word = param.get("sensitive_word")
        if not file_type or not level or (file_type == 2 and not sensitive_word):
            res["status"] = 1
            res["msg"] = "请检查参数"
        else:
            if file_type != 2:
                # 接收上传文件
                file_obj = request.FILES.get("upFile")
                if file_obj.size > 200 * 1024 * 1024:
                    res["status"] = 1
                    res["msg"] = "文件过大"
                    return Response(res)
                name = file_obj.name
                store_file = os.path.join(BASE_DIR, "filesecurity/temp_file/" + name)
                with open(store_file, "wb") as f:
                    for chunk in file_obj.chunks():
                        f.write(chunk)
                with open(store_file, "rb") as f:
                    file_md5_value = file_md5(f.read())
            else:
                file_md5_value = ""
                name = sensitive_word
            new_fm = FileManagement(name=name, file_md5=file_md5_value, level=level, file_type=file_type,
                                    sensitive_word=sensitive_word)
            new_fm.save()
    elif request.method == "DELETE":
        param = json.loads(request.body)
        fm_id = param.get("id")
        fm = FileManagement.objects.filter(id=fm_id).all()
        if not fm or not fm_id:
            res["msg"] = "文件无效"
            res["status"] = 1
        else:
            fm = fm[0]
            fm.status = 0
            fm.save()
    return Response(res)


@api_view(["POST"])
def sen_mark(request):
    res = dict()
    res["status"] = 0
    res["msg"] = "success"
    param = json.loads(request.body)
    file_id = param.get("id")
    sen_level = param.get("sen_level", 0)
    filelog = FileLog.objects.filter(id=file_id).all()
    if not file_id or not filelog:
        res["status"] = 1
        res["msg"] = "无效文件，检查传入参数"
    filelog = filelog[0]
    # query = {"filename": filelog.filename}
    query = {"md5": filelog.md5}
    update_values = {"$set": {"sen_level": sen_level, "sen_type": 1}}
    file_collections = collections["files"]
    file_collections.update_one(query, update_values)
    # 新增一条文件管理记录
    # new_fm = FileManagement.objects.get_or_create(name=filelog.filename)[0]
    new_fm = FileManagement.objects.get_or_create(file_md5_value=filelog.md5)[0]
    new_fm.level = sen_level
    new_fm.file_type = 1
    new_fm.save()
    return Response(res)


@api_view(["GET"])
def sens_search(request):
    res = dict()
    res["msg"] = "success"
    res["status"] = 0
    res["data"] = dict()
    username = request.GET.get("username")
    file_md5_value = request.GET.get("md5_value")
    user = ZTPUser.objects.filter(enabled=True, username=username).all()
    if not user:
        res["msg"] = "没有找到对应的用户，请检查传入的用户名"
        res["status"] = 1
        return Response(res)
    user = user[0]
    us = UserScore.objects.filter(user=user).all()
    if us:
        score = us[0].safety_score
    else:
        score = 980
    score_level = check_safety_level(score)
    if score_level < 2:
        # 检查是否有匹配的md5敏感文件
        fmobjet = FileManagement.objects.filter(file_md5=file_md5_value, status=1).all()
        if not fmobjet:
            queryset = FileManagement.objects.filter(file_md5="", status=1).all()
            sens_list = [{"sensitive_word": f.sensitive_word, "level": f.level} for f in queryset]
            res["data"]["sens_word"] = sens_list
            res["data"]["level"] = 0
        else:
            res["data"]["sens_word"] = []
            res["data"]["level"] = fmobjet[0].level
        res["data"]["safety_level"] = score_level
    else:
        res["data"]["sens_word"] = []
        res["data"]["level"] = 0
        res["data"]["safety_level"] = score_level
        str_list = []
        for i in res["data"]["sens_word"]:
            if i.get("sensitive_word"):
                str_list.append(i.get("sensitive_word"))
        res["data"]["sens_word_str"] = ",".join(str_list)
    return Response(res)


def check_safety_level(score):
    """
    :param score: 用户得分
    :return: 安全评分等级，有五个等级，0表示low,1表示medium,2表示good,3表示excellent, 4表示perfect
    """
    from ztp_backend.settings import LOW_SCORE, GOOD_SCORE, MEDIUM_SCORE, PERFECT_SCORE, EXCELLENT_SCORE
    if score >= LOW_SCORE[0] and score <= LOW_SCORE[1]:
        return 0
    elif score >= MEDIUM_SCORE[0] and score <= MEDIUM_SCORE[1]:
        return 1
    elif score >= GOOD_SCORE[0] and score <= GOOD_SCORE[1]:
        return 2
    elif score >= PERFECT_SCORE[0] and score <= PERFECT_SCORE[1]:
        return 4
    elif score >= EXCELLENT_SCORE[0] and score <= EXCELLENT_SCORE[1]:
        return 5
